aa80626764
Manual /compress on a compute-host (turn_isolation) session blocked its RPC waiter for a hard-coded 120s, answered error 5019, and then DROPPED the host's late `control.ack`: HostSupervisor.control() popped the pending queue in `finally`, so `_handle_host_frame` had nothing to deliver to. The host kept compressing, succeeded minutes later, rotated the session — and the gateway session never mirrored the new session_key/history_version and the desktop never refreshed its transcript. - host_supervisor: `control(..., on_late_ack=)` leaves a one-shot handler registered when the waiter times out; control.ack/control.error/error frames for that request_id fire it (bounded: 30min TTL, cap 64). A host crash fails outstanding handlers with a synthetic control.error. - server: `_compute_host_compress_wait_seconds()` derives the wait from `compression.context_total_ceiling_seconds` (+30s slack, floor 120s, cap 630s) instead of the literal 120. `_adopt_late_compute_host_compress_ack` applies the metadata mirror and emits the same `session.info` a normal compress does plus the existing `status.update kind=compacted` edge; a late error goes out through the existing `error` event. - session.compress / slash.compress (methods_tools + _mirror_slash_side_effects): on waiter timeout answer `status: pending` (not 5019) and register the late-ack handler. - desktop: SESSION_COMPRESS_TIMEOUT_MS 120s -> 660s (above the gateway cap); `status: 'pending'` renders as an info notice, not `error:`; the `compacted` status edge rehydrates an idle active session's transcript (mid-turn compaction still defers to the turn settle path). Minimal extraction of the design in #99630 by @vsd2807 (design trace by @andrexibiza and @JoaoMarcos44 in the #97948 thread); no new DB tables, modules, or polling protocol. Refs #97948 Co-authored-by: VVV <vaibhavdahiya28@gmail.com>