Follow-up from the #326 code review (finding #2).
Context
#326 makes the heartbeat tick refuse to advertise a dead tunnel hostname and restart clawbox-tunnel instead. That's the right call for the common case (restart mints a fresh URL the next tick pushes).
The gap
On a dead verdict the tick does not call pushHeartbeatTick. If the restart keeps failing (Cloudflare can't mint a tunnel, or the service won't restart), the box sends no heartbeat and the portal flips it Offline after the staleness window — the alive box disappears from fleet ops entirely, instead of showing Online-with-no-working-link.
pushHeartbeatTick(url) no-ops on a null URL, so there's no way today to say "box is alive, tunnel is not."
Proposed fix
Add an alive-without-URL heartbeat: push a liveness signal that carries box state (lastSeenAt) but explicitly no/blank tunnel URL, and have the portal render that as Online — Remote Access unavailable rather than a dead link or Offline. Then the dead branch can push that while it restarts.
This is a portal-protocol change (box + portal side), which is why it was scoped out of #326.
Follow-up from the #326 code review (finding #2).
Context
#326 makes the heartbeat tick refuse to advertise a dead tunnel hostname and restart
clawbox-tunnelinstead. That's the right call for the common case (restart mints a fresh URL the next tick pushes).The gap
On a
deadverdict the tick does not callpushHeartbeatTick. If the restart keeps failing (Cloudflare can't mint a tunnel, or the service won't restart), the box sends no heartbeat and the portal flips it Offline after the staleness window — the alive box disappears from fleet ops entirely, instead of showing Online-with-no-working-link.pushHeartbeatTick(url)no-ops on a null URL, so there's no way today to say "box is alive, tunnel is not."Proposed fix
Add an alive-without-URL heartbeat: push a liveness signal that carries box state (lastSeenAt) but explicitly no/blank tunnel URL, and have the portal render that as Online — Remote Access unavailable rather than a dead link or Offline. Then the
deadbranch can push that while it restarts.This is a portal-protocol change (box + portal side), which is why it was scoped out of #326.