fix(daemon): replace fixed 15s startup kill with progress-aware startup budget

TH
25m ago
+1825-673

Summary

Closes #3782. A client killed a healthy daemon that was still starting: local startup used one 15 s wall-clock deadline, so an overloaded host failed the run before any work started (#3342).

startLocalDaemon now waits while the spawned daemon stays alive, to a 120 s ceiling; AGENT_DEVICE_DAEMON_STARTUP_TIMEOUT_MS overrides it for CLI, MCP, and Node. Each launch claims and records phase markers (modules-loaded…registered) in its own daemon-startup-phases-<pid>.jsonl, attributed by file name and a fresh lifetime claim. Owners retire it: the daemon after registered, the client after any joined terminal exit, the registration owner on sweep of provably-dead pids. Silent 60 s fails startup-stalled; an exit fails fast (startup-exited). Any deadline with a live startup still pending — this client's launch or a verified live lock owner — fails startup-ceiling with reason, phases, startupTimeoutMs; a live contender is never signaled. No CI auto-detection.

Scope expansions: the iOS preflight times the public SDK ensureDaemon() after clean:daemon, logging a daemon_cold_startup record. The CLI daemon_startup timer wraps only attach, so it cannot be cold-startup evidence.

Validation

Head f45bc9d470, base 4a8abed7b9, 18 files, gross 2498. check:affected --run --head f45bc9d470: passed, exactCommit=true, checkoutChanged=false (receipt run-Hh9oLH). Ceiling-defect regression red at bef883fbc1 / green at head through sendToDaemon. Eager budgets (OUTPUT_ECONOMY_BASE=4a8abed7b9): 846/846. Leak integrations pass. Cold-startup CI evidence at bef883fbc1: durationMs:324, started:true (run 39076295261); new-head CI pending. Integration, Coverage, native, device lanes stay GitHub-owned at this head.