Yes. I assume as well after reading the docs and forum! So, recommend you shorten the time between keep.Alive()'s or send a periodic ping. I do both.
It varies. Sometimes I have seen the devices go online within an hour to 3. Other times - never.
Yes. As Paul_M was referring to - things seem to have changed. I use a watchdog to look at diagnostics and force a System.reset() before my device goes offline. You might already be using the library:
Some example statements I use from the DiagnosticHelperRK library are:
g_cloudConnectionStatus = DiagnosticsHelper::getValue(DIAG_ID_CLOUD_CONNECTION_STATUS);
// connected = 2 connecting = ??????
and
g_cloudConnectionErrorCode = DiagnosticsHelper::getValue(DIAG_ID_CLOUD_CONNECTION_ERROR_CODE);
// error code = 0 (no error) 10(?????) 17(?????)
One last option you might consider: How to force a handshake for OTA updates - #30 by ScruffR
Last, is an example I use while connected to cloud to force a new session (force a handshake):
Particle.publish("spark/device/session/end", "", PRIVATE);
// will FORCE NEW SESSION AFTER DISCONNECT!!!!!!!!!
softDelay(1000);