* fix(mobile): open the Resume workspace through a mounted host stack
Tapping Resume on Home landed on a blank host screen instead of the
session. A cold push straight into the nested /h/[hostId] navigator
resolves to the host index route without the dynamic id, so
HostProtocolGate mounts with hostId undefined and never connects.
Home already worked around this for the host editor (#11635) and Tasks
(#11853) by mounting /h/[hostId] first and replacing it once the stack
is committed. Extract that mechanism into host-stack-navigation so
Resume uses the same transition instead of a direct push.
The previous Resume fix (#11876) swapped the manual href for a typed
dynamic href, but expo-router's encodeParam already applies
encodeURIComponent to dynamic segments, so it resolved to the same URL
the manual string produced and left the cold-navigator path unchanged.
Claude-Session: https://claude.ai/code/session_01RMoaxp7MLg2ydP28KFLX7B
* fix(mobile): harden the host-stack transition after bot review
- match a host route committed as the encoded segment it was pushed as,
so an id containing `/`, `#`, or `%` still triggers the REPLACE
- share one pending transition across the Home entry points; per-hook
refs let a Tasks tap and a Resume tap arm two pushes that could not
cancel each other
- assert the source markers before slicing in the Resume wiring test
Claude-Session: https://claude.ai/code/session_01RMoaxp7MLg2ydP28KFLX7B
* test(mobile): lock the host-stack transition state machine
Assert the replace waits for the host mount (zero dispatches before it,
exactly one after), and cover cancel/retarget — the paths the shared
pending transition relies on.
* test(mobile): model listener removal in the navigation harness
A no-op unsubscribe let setState keep calling a canceled listener, so the
teardown assertions only exercised the active guard. Dropping the
unsubscribe call from dispose now fails the suite.
---------
Co-authored-by: kaynan <kaynan.camargo@terceiro-sky.com.br>