- m9: shared_metrics.startup_latency had no server-side latch, so any repeat
call added a row. The TUI and Desktop now send an opaque per-launch id
(TUI: one per process; Desktop: minted when the once-per-launch main-process
claim succeeds) and the backend claims (surface, launch_id) once per
process: a reconnect re-sending the same launch counts once, a new Desktop
launch against a long-lived backend still counts. Legacy clients without an
id count once per backend process and surface. The id is only a local latch
key (bounded set, length-capped), never recorded. Only a usable measurement
spends the claim. Contract + apps/shared regenerated.
- m10: relaunch() execs in place, keeping the PID, so `sessions browse` ->
resume counted the picker time as CLI startup. relaunch() stamps its PID in
HERMES_RELAUNCHED_PID right before exec; process-start surfaces skip when it
matches, while children (other PIDs) inheriting the env still count.
- m8 (psutil half): record_process_ready checks the opt-in gate before reading
the process start time (psutil) or starting a thread. The claim is taken
first so a later opt-in never records a stale "startup" mid-session.
Test changes to existing assertions: the TUI/Desktop param assertions now
expect launch_id (a new wire param); the RPC surface test sends distinct
launch ids so its three calls stay three launches under the new latch.